﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Microsoft.EntityFrameworkCore;
namespace Assignment9.Models
{

    public class OrderService
    {
        OrderContext Context;
        public OrderService(OrderContext Context)
        {
            this.Context = Context;
        }
        public List<Order> AllOrder()
        {

            return Context.Orders.Include(o => o.Details.Select(d => d.goods)).Include(o => o.Customer)
            .ToList();

        }

        //新增订单
        public void AddOrder(Order order)
        {
            FixOrder(order);
            Context.Entry(order).State = EntityState.Added;
            Context.SaveChanges();

        }
        public void AddOrder(Customer c, List<OrderDetail> details, Time time)
        {
            Order order = new Order(c, details, time);
            AddOrder(order);
        }
        //删除订单
        public void RemoveOrder(List<Order> orders)
        {
            if (Search(orders).Count == 0) throw new NotFoundException("Order with this ID is not found!");
            Search(orders).ForEach(o => { Context.Orders.Remove(o); Order.number--; });
        }
        public void RemoveOrder(string ID)
        {

            var order = Context.Orders.Include("Details")
              .SingleOrDefault(o => o.ID == ID);
            if (order == null) return;
            Context.OrderDetails.RemoveRange(order.Details);
            Context.Orders.Remove(order);
            Context.SaveChanges();

        }

        //修改订单
        public void modifyOrder(string ID, Customer c)
        {
            var query = Context.Orders.Where(o => o.ID == ID);
            if (query.ToList().Count == 0) throw new NotFoundException("Order with this ID is not found!");
            if (query.ToList().Count > 1) throw new RepleteException("Order with this ID is more than one!");
            query.ToList()[0] = modify(query.ToList()[0], c);
        }
        public void modifyOrder(string ID, List<OrderDetail> details)
        {
            var query = Context.Orders.Where(o => o.ID == ID);
            if (query.ToList().Count == 0) throw new NotFoundException("Order with this ID is not found!");
            if (query.ToList().Count > 1) throw new RepleteException("Order with this ID is more than one!");
            query.ToList()[0] = modify(query.ToList()[0], details);
        }

        public void modifyOrder(string ID, Time t)
        {
            var query = Context.Orders.Where(o => o.ID == ID);
            if (query.ToList().Count == 0) throw new NotFoundException("Order with this ID is not found!");
            if (query.ToList().Count > 1) throw new RepleteException("Order with this ID is more than one!");
            query.ToList()[0] = modify(query.ToList()[0], t);
        }
        public Order modify(Order order, Customer c)
        {
            order.setCustomer(c);
            return order;
        }
        public Order modify(Order order, List<OrderDetail> details)
        {
            order = new Order(order.GetCustomer(), details, order.GetTime());
            return order;
        }
        public Order modify(Order order, Time t)
        {
            order.setTime(t);
            return order;
        }


        //查询订单
        public List<Order> Search(string[] orderID)
        {


            return Context.Orders
              .Include(o => o.Details.Select(d => d.goods))
              .Include(o => o.Customer)
              .Where(o => orderID.Contains(o.ID)).OrderBy(o => o.Amount)
              .ToList();

        }
        public List<Order> Search(string orderID)
        {


            return Context.Orders
              .Include(o => o.Details.Select(d => d.goods))
              .Include(o => o.Customer)
              .Where(o => orderID == o.ID).OrderBy(o => o.Amount)
              .ToList();

        }
        public List<Order> Search(OrderDetail detail)
        {

            return Context.Orders
              .Include(o => o.Details.Select(d => d.goods))
              .Include(o => o.Customer)
              .Where(o => o.GetOrderDetails().Where(d => d.goods.Name == detail.goods.Name).Count() == 1).OrderBy(o => o.Amount)
              .ToList();
        }


        public List<Order> Search(Customer c)
        {

            return Context.Orders
              .Include(o => o.Details.Select(d => d.goods))
              .Include(o => o.Customer)
              .Where(o => o.GetCustomer().getName().Equals(c.getName())).OrderBy(o => o.Amount)
              .ToList();

        }

        public List<Order> Search(List<Order> orders)
        {

            return Context.Orders
              .Include(o => o.Details.Select(d => d.goods))
              .Include(o => o.Customer)
              .Where(o => orders.Contains(o)).OrderBy(o => o.Amount)
              .ToList();

        }
        //查找所有总金额超过某个金额的订单
        public List<Order> Search(double amount1)
        {

            return Context.Orders
              .Include(o => o.Details.Select(d => d.goods))
              .Include(o => o.Customer)
              .Where(o => o.Amount - amount1 >= 0).OrderBy(o => o.Amount)
              .ToList();

        }
        public void UpdateOrder(Order newOrder)
        {
            RemoveOrder(newOrder.ID);
            AddOrder(newOrder);
        }


        private static void FixOrder(Order newOrder)
        {
            newOrder.Customer = null;
            newOrder.Details.ForEach(d =>
            {
                d.GoodsPrice = d.goods.getPrice().ToString();
                d.goods = null;
            });
        }

        public void Export(String fileName)
        {
            XmlSerializer xs = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                xs.Serialize(fs, AllOrder);
            }
        }

        public void Import(string path)
        {
            XmlSerializer xs = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream(path, FileMode.Open))
            {

                List<Order> temp = (List<Order>)xs.Deserialize(fs);
                temp.ForEach(order =>
                {
                    if (Context.Orders.SingleOrDefault(o => o.ID == order.ID) == null)
                    {
                        //FixOrder(order);
                        Context.Orders.Add(order);
                    }
                });
                Context.SaveChanges();
            }
        }
    }

    public class NotFoundException : Exception
    {
        public NotFoundException(string message) : base(message)
        {
        }
    }

    public class RepleteException : Exception
    {
        public RepleteException(string message) : base(message)
        {

        }
    }

}
